<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/24
 * Time: 16:57
 */
namespace backend\services;
use backend\models\Baseorders;
use backend\models\Baseproducts;
use backend\models\DurationPermission;
use backend\models\PackItem;
use backend\models\PackPlayer;
use backend\models\PlayerCurrencyRecordTbl;
use backend\models\PlayerMoneyModify;
use backend\models\PlayerTbl;
use backend\common\PubService;
use backend\components\String;
use backend\models\RoleBuyRecord;
use backend\models\RolePlayerInfo;
use backend\models\SystemMail;
use yii;

class PayService
{
    /**
     * 通过跳转获取用户的openid，跳转流程如下：
     * 1、设置自己需要调回的url及其其他参数，跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
     * 2、微信服务处理完成之后会跳转回用户redirect_uri地址，此时会带上一些参数，如：code
     * @return 用户的openid
     */
    public function GetOpenid($pid, $userid)
    {
        //通过code获得openid
        if (!isset($_GET['code'])){
            //触发微信返回code码
            //$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
            $redirect_url = yii::$app->params['wx_url'].'?id='.$pid.'&userid='.$userid;
            $baseUrl = yii::$app->params['ty_wx_url'].urlencode($redirect_url);
            Header("Location: $baseUrl");
            exit();
        } else {
            //获取code码，以获取openid
            $code = $_GET['code'];
            $openid = $this->GetOpenidFromMp($code);
            return $openid;
        }
    }


    public function get_user_info($redirect_url)
    {
        if (!isset($_GET['code'])){
            $baseUrl = yii::$app->params['ty_wx_url'].$redirect_url;
            Header("Location: $baseUrl");
            exit();
        } else {
            $code = $_GET['code'];
            $data = $this->GetOpenidAccessTokenFromMp($code);
            $union_url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $data['access_token'] . '&openid=' . $data['openid']. '&lang=zh_CN';
            $res = self::curlGet($union_url);
            $data = json_decode($res,true);
            return $data;
        }
    }


//    public function get_shopping_openid($pid)
//    {
//        //通过code获得openid
//        if (!isset($_GET['code'])){
//            //触发微信返回code码
//            //$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
//            $wx_url = 'http://m.bywlsz.com/pay/order-preview?id='.$pid;
//            $baseUrl = urlencode($wx_url);
//            $url = $this->__CreateOauthUrlForCode($baseUrl);
//            Header("Location: $url");
//            exit();
//        } else {
//            //获取code码，以获取openid
//            $code = $_GET['code'];
//            $openid = $this->GetOpenidFromMp($code);
//            return $openid;
//        }
//    }


    /**
     * 通过code从工作平台获取openid机器access_token
     * @param string $code 微信跳转回来带上的code
     * @return openid
     */
    public function GetOpenidFromMp($code)
    {
        $url = $this->__CreateOauthUrlForOpenid($code);
        $res = self::curlGet($url);
        //取出openid
        $data = json_decode($res,true);
        //$openid = $data['openid'];
        try {
            $openid = $data['openid'];
            if ($openid) {
                //一天缓存
                Yii::$app->session->set(md5('openid'), $openid);
            }
        } catch (\Exception $ex) {
//            $openid = str_replace('-', '', String::uuid());
//            Yii::$app->session->set(md5('openid'), $openid);
            $openid = yii::$app->session->get(md5('openid'));
        }
        return $openid;
    }

    /**
     * 通过code从工作平台获取openid机器access_token
     * @param string $code 微信跳转回来带上的code
     * @return openid
     */
    public function GetOpenidAccessTokenFromMp($code)
    {
        $url = $this->__CreateOauthUrlForOpenid($code);
        $res = self::curlGet($url);
        //取出openid
        $data = json_decode($res,true);
        try {
            if ($data['openid']) {
                //一天缓存
                Yii::$app->session->set(md5('openid'), $data['openid']);
                Yii::$app->session->set(md5('access_token'), $data['access_token']);
            }
        } catch (\Exception $ex) {
//            $openid = str_replace('-', '', String::uuid());
//            Yii::$app->session->set(md5('openid'), $openid);
            $data['openid'] = yii::$app->session->get(md5('openid'));
            $data['access_token'] = yii::$app->session->get(md5('access_token'));
        }
        return $data;
    }


    /**
     * 构造获取open和access_toke的url地址
     * @param string $code，微信跳转带回的code
     * @return 请求的url
     */
    private function __CreateOauthUrlForOpenid($code)
    {
        $urlObj["appid"] = yii::$app->params['wxpay_config']['appid'];
        $urlObj["secret"] = yii::$app->params['wxpay_config']['secret'];
        $urlObj["code"] = $code;
        $urlObj["grant_type"] = "authorization_code";
        $bizString = $this->ToUrlParams($urlObj);
        return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
    }


    /**
     * 构造获取code的url连接
     * @param string $redirectUrl 微信服务器回跳的url，需要url编码
     * @return 返回构造好的url
     * 静默状态下获取用户
     */
    private function __CreateOauthUrlForCode($redirectUrl)
    {
        $urlObj["appid"] = yii::$app->params['wxpay_config']['appid'];//$this->appid;
        $urlObj["redirect_uri"] = "$redirectUrl";
        $urlObj["response_type"] = "code";
        $urlObj["scope"] = "snsapi_base";
        $urlObj["state"] = "STATE"."#wechat_redirect";
        $bizString = $this->ToUrlParams($urlObj);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
    }


    /**
     * 构造获取code的url连接
     * @param string $redirectUrl 微信服务器回跳的url，需要url编码
     * @return 返回构造好的url
     * 待用户确定状态下获取用户
     */
    private function __CreateUserForCode($redirectUrl)
    {
        $urlObj["appid"] = yii::$app->params['wxpay_config']['appid'];//$this->appid;
        $urlObj["redirect_uri"] = "$redirectUrl";
        $urlObj["response_type"] = "code";
        $urlObj["scope"] = "snsapi_userinfo";
        $urlObj["state"] = "STATE"."#wechat_redirect";
        $bizString = $this->ToUrlParams($urlObj);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
    }


    /**
     * 拼接签名字符串
     * @param array $urlObj
     * @return 返回已经拼接好的字符串
     */
    private function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v)
        {
            if($k != "sign") $buff .= $k . "=" . $v . "&";
        }
        $buff = trim($buff, "&");
        return $buff;
    }


    /**
     * 订单成功生成后进行支付行为
     */
    public function orderPay($orderId, $payStatus, $openId)
    {
        //统一下单
        $data = Baseorders::find()->where(['OrderId' => $orderId])->asArray()->one();
        $outTradeNo = $orderId;     //商品订单号
        $payAmount = $data['Amount'];//付款金额，单位:0.01元$data['Amount']
        $product = Baseproducts::findOne(['ProductId'=>$data['ProductId']]);    //订单标题
        $orderName = $product->ProductName;
        $notifyUrl = yii::$app->params['notifyUrl'];     //付款成功后的回调地址
        $ali_notifyUrl = yii::$app->params['alipay_config']['notify_url'];
        $ali_returnUrl = yii::$app->params['alipay_config']['return_url'];
        $payTime = time();      //付款时间
        if (empty($payStatus)){//微信H5支付
            $H5Parame = self::createBizPackage($openId,$payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime,$payStatus);
            $redirect_url = yii::$app->params['redirect_url'].'?out_trade_no='.$orderId;
            $redirect_url = $H5Parame['mweb_url'].'&redirect_url='.urlencode($redirect_url);
            return ['statusCode'=>200, 'message'=>$redirect_url];
        }else{
            if ($payStatus == 1){//支付宝H5支付
                $url = self::alipay($payAmount, $outTradeNo, $orderName, $ali_returnUrl,$ali_notifyUrl);
                return ['statusCode'=>200, 'message'=>$url];
            }elseif ($payStatus == 2){//苹果内购
                return ['statusCode'=>200, 'message'=>'', 'OrderId'=>$outTradeNo, 'UserId'=>$data['UserId']];
            }elseif ($payStatus == 3){//微信APP支付
                $JsApiParame = self::createBizPackage($openId,$payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime,$payStatus);
                return ['statusCode'=>200, 'message'=>$JsApiParame];
            }elseif ($payStatus == 4){//微信公众号支付
                $JsApiParame = self::createBizPackage($openId,$payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime,$payStatus);
                return ['statusCode'=>200, 'message'=>$JsApiParame];
            }elseif ($payStatus == 5){
                //小程序支付
            }elseif ($payStatus == 6){
                //华为内支付
                $JsApiParame = self::huaweiPay($data['RequestId'],$data['ProductId'],$payAmount,$outTradeNo,$orderName);
                return ['statusCode'=>200, 'Sign'=>$JsApiParame, 'OrderId'=>$outTradeNo, 'UserId'=>$data['UserId']];
            }elseif ($payStatus == 7){
                //小米支付
                $JsApiParame = self::xiaomiPay($data['ProductId'],$outTradeNo,$orderName,$data['UserId']);
                return ['statusCode'=>200, 'signature'=>$JsApiParame, 'cpOrderId'=>$outTradeNo, 'UserId'=>$data['UserId']];
            }
        }
    }

    /**
     * 小米支付
     */
    public static function xiaomiPay($productNo, $outTradeNo, $orderName, $uid)
    {
        $params = [
            'appId' => yii::$app->params['xiaomi_config']['app_id'],
            'cpOrderId' => $outTradeNo,
            'payFee' => 1,
            'productCode' => 'XM_'.$productNo,
            'productCount' => 1,
            'productName' => $orderName,
            'uid' => $uid,
        ];
        return self::xiaomisign($params, yii::$app->params['xiaomi_config']['app_secret']);
    }

    /**
     * 计算hmac-sha1签名
     * @param array $params
     * @param type $secretKey
     * @return type
     */
    public static function xiaomisign($params, $secretKey){
        $sortString = self::xiaomibuildSortString($params);
        $signature = hash_hmac('sha1', $sortString, $secretKey,FALSE);
        return $signature;
    }

    /**
     * 验证签名
     * @param array $params
     * @param type $signature
     * @param type $secretKey
     * @return type
     */
    public function verifySignature($params, $signature) {
        $tmpSign = self::xiaomisign($params, yii::$app->params['xiaomi_config']['app_secret']);
        return $signature == $tmpSign ? TRUE : FALSE;
    }

    /**
     * 构造排序字符串
     * @param array $params
     * @return string
     */
    public static function xiaomibuildSortString(array $params) {
        if(empty($params)){
            return '';
        }
        ksort($params);
        $fields = array();
        foreach ($params as $key => $value) {
            $fields[] = $key . '=' . $value;
        }
        return implode('&',$fields);
    }

    /**
     * url decode 函数
     * @param type $item 数组或者字符串类型
     * @return type
     */
    public function xiaomiurlDecode($item){
        if(is_array($item)){
            return array_map(array(&$this,'urlDecode'), $item);
        }
        return rawurldecode($item);
    }

    /**
     * 华为支付
     */
    public static function huaweiPay($requestId,$productNo,$totalFee, $outTradeNo, $orderName)
    {
        $productPayRequest = array(
            'productNo' => 'hw_'.$productNo,
            'applicationID' => yii::$app->params['huawei_config']['app_id'],
            'requestId' => $requestId,
            'merchantId' => yii::$app->params['huawei_config']['cp_id'],
            'sdkChannel' => 1,
            'url' => yii::$app->params['huawei_config']['notify_url'],
            'urlver'=> '2',
        );
        return self::generateHuaweiSign($productPayRequest, yii::$app->params['huawei_config']['sign_type']);
    }


    /**
     * 微信支付函数
     */
    public static function createBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp,$payStatus)
    {
        $params = yii::$app->params;
        $net_url = $params['net_url'];
        $unified = array(
            'appid' => $params['wxpay_config']['appid'],
            'mch_id' => $params['wxpay_config']['mchid'],
            'nonce_str' => self::createNonceStr(),
            'body' => $orderName,
            'notify_url' => $notifyUrl,
            'out_trade_no' => $outTradeNo,
            'spbill_create_ip' => PubService::real_ip(),
            'total_fee' => intval( $totalFee * 100),       //单位 转为分
            'trade_type' => empty($payStatus) ? 'MWEB' : (($payStatus == 3) ? 'APP' : 'JSAPI') ,
        );
        if (empty($payStatus)){
            $unified['scene_info'] = '{"h5_info":{"type":"Wap","wap_url":'.$net_url.',"wap_name":"百游网络"}}';
        }else{
            $unified['openid'] = $openid;//trade_type=JSAPI，此参数必传
        }
        $unified['sign'] = self::getSign($unified, $params['wxpay_config']['key']);
        $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified));
        if (!$responseXml){
            return ['statusCode'=>0, 'messgage'=>"Can't connect the server"];
        }
        $unifiedOrder = self::FromXml($responseXml);
        if (strval($unifiedOrder['return_code']) != 'SUCCESS'){
            return ['statusCode'=>0, 'messgage'=>strval($unifiedOrder['return_msg'])];
        }
        if (strval($unifiedOrder['result_code']) != 'SUCCESS'){
            return ['statusCode'=>0, 'messgage'=>strval($unifiedOrder['err_code']).':'.strval($unifiedOrder['err_code_des'])];
        }
        if (empty($payStatus)){//H5
            return $unifiedOrder;
        } elseif ($payStatus == 3){
            return $unifiedOrder;
        } else{
            settype($timestamp, "string");
            $resdata = array(
                'appId'         => strval($unifiedOrder['appid']),
                'nonceStr'      => strval($unifiedOrder['nonce_str']),
                'package'       => 'prepay_id='.strval($unifiedOrder['prepay_id']),
                'signType'      => 'MD5',
                'timeStamp'     => $timestamp
            );
            $resdata['paySign'] = self::getSign($resdata, $params['wxpay_config']['key']);
            $resdata['out_trade_no'] = $outTradeNo;
            return json_encode($resdata);
        }

    }


    public static function curlGet($url = '', $options = array())
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }


    public static function curlPost($url = '', $postData = '', $options = array())
    {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }


    public static function createNonceStr($length = 16)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $str = '';
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }


    public static function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
        }
        $xml .= "</xml>";
        return $xml;
    }


    public static function getSign($params, $key)
    {
        ksort($params, SORT_STRING);
        $unSignParaString = self::formatQueryParaMap($params, false);
        $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
        return $signStr;
    }


    protected static function formatQueryParaMap($paraMap, $urlEncode = false)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }


    /**
     *
     * 支付结果通用通知
     * @param function $callback
     * 直接回调函数使用方法: notify(you_function);
     * 回调类成员函数方法:notify(array($this, you_function));
     * $callback  原型为：function function_name($data){}
     */
    public static function notify()
    {
        $xml = $_REQUEST;
        if($xml == null){
            $xml = file_get_contents("php://input");
        }
        return $xml;
    }


    /**
     * 将xml转为array
     * @param string $xml
     * @throws WxPayException
     */
    public static function FromXml($xml)
    {
        if(!$xml){
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }


    /**
     * 支付宝支付
     */
    public static function alipay($totalFee, $outTradeNo, $orderName, $returnUrl,$notifyUrl)
    {
        //请求参数
        $requestConfigs = array(
            'out_trade_no'=> $outTradeNo,
            'total_amount'=> $totalFee, //单位 元
            'subject'=> $orderName,  //订单标题
        );
        $commonConfigs = array(
            //公共参数
            'app_id' => yii::$app->params['alipay_config']['app_id'],
            'method' => yii::$app->params['alipay_config']['method'],
            'format' => yii::$app->params['alipay_config']['format'],
            'return_url' => $returnUrl,
            'charset'=> yii::$app->params['alipay_config']['charset'],
            'version' => '1.0',
            'sign_type'=> yii::$app->params['alipay_config']['sign_type'],
            'timestamp'=>date('Y-m-d H:i:s', time()),
            'notify_url' => $notifyUrl,
            'biz_content'=>json_encode($requestConfigs),
        );
        $commonConfigs["sign"] = self::generateSign($commonConfigs, $commonConfigs['sign_type']);
        return self::buildRequestForm($commonConfigs);
    }

    /**
     * 建立请求，以表单HTML形式构造（默认）
     * @param $para_temp 请求参数数组
     * @return 提交表单HTML文本
     */
    public static function buildRequestForm($para_temp) {

        $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".yii::$app->params['alipay_config']['gatewayUrl']."?charset=".yii::$app->params['alipay_config']['charset']."' method='POST'>";
        while (list ($key, $val) = each ($para_temp)) {
            if (false === self::checkEmpty($val)) {
                $val = str_replace("'","&apos;",$val);
                $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
            }
        }
        //submit按钮控件请不要含有name属性
        $sHtml = $sHtml."<input type='submit' value='ok' style='display:none;'></form>";
        $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
        return $sHtml;
    }


    public static function generateSign($params, $signType = "RSA") {
        return self::sign(self::getSignContent($params), $signType);
    }

    public static function generateHuaweiSign($params, $signType = "RSA2") {
        return self::HuaweiSign(self::getSignContent($params), $signType);
    }

    public static  function HuaweiSign($data, $signType = "RSA2") {
        $priKey = yii::$app->params['huawei_config']['huawei_private_key'];
        $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($priKey, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";
        ($res) or die('您使用的私钥格式错误，请检查RSA私钥配置');
        if ("RSA2" == $signType) {
            openssl_sign($data, $sign, $res, version_compare(PHP_VERSION,'5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持
        } else {
            openssl_sign($data, $sign, $res);
        }
        $sign = base64_encode($sign);
        return $sign;
    }


    public static  function sign($data, $signType = "RSA") {
        $priKey = yii::$app->params['alipay_config']['alipay_private_key'];
        $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($priKey, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";
        ($res) or die('您使用的私钥格式错误，请检查RSA私钥配置');
        if ("RSA2" == $signType) {
            openssl_sign($data, $sign, $res, version_compare(PHP_VERSION,'5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持
        } else {
            openssl_sign($data, $sign, $res);
        }
        $sign = base64_encode($sign);
        return $sign;
    }


    /**
     * 校验$value是否非空
     *  if not set ,return true;
     *    if is null , return true;
     **/
    public static function checkEmpty($value) {
        if (!isset($value))
            return true;
        if ($value === null)
            return true;
        if (trim($value) === "")
            return true;
        return false;
    }


    public static function getSignContent($params) {
        ksort($params);
        $stringToBeSigned = "";
        $i = 0;
        foreach ($params as $k => $v) {
            if (false === self::checkEmpty($v) && "@" != substr($v, 0, 1)) {
                // 转换成目标字符集
                $v = self::characet($v, yii::$app->params['alipay_config']['charset']);
                if ($i == 0) {
                    $stringToBeSigned .= "$k" . "=" . "$v";
                } else {
                    $stringToBeSigned .= "&" . "$k" . "=" . "$v";
                }
                $i++;
            }
        }
        unset ($k, $v);
        return $stringToBeSigned;
    }


    /**
     * 转换字符集编码
     * @param $data
     * @param $targetCharset
     * @return string
     */
    public static function characet($data, $targetCharset) {
        if (!empty($data)) {
            $fileType = yii::$app->params['alipay_config']['charset'];
            if (strcasecmp($fileType, $targetCharset) != 0) {
                $data = mb_convert_encoding($data, $targetCharset, $fileType);
                //$data = iconv($fileType, $targetCharset.'//IGNORE', $data);
            }
        }
        return $data;
    }


    /**
     * @param $receipt_data
     * @param int $sandbox
     * @return mixed
     * 苹果内购
     */
    public static function apple_curl($receipt_data, $sandbox=0){
        //小票信息
        $POSTFIELDS = array("receipt-data" => $receipt_data);
        $POSTFIELDS = json_encode($POSTFIELDS);
        //正式购买地址 沙盒购买地址
        $url_buy     = "https://buy.itunes.apple.com/verifyReceipt";
        $url_sandbox = "https://sandbox.itunes.apple.com/verifyReceipt";
        $url = $sandbox ? $url_sandbox : $url_buy;
        //简单的curl
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }


    /**
     * wechat and alipay notify result
     * 微信和支付宝异步后数据处理
     */
    public function getNotifyResult($data, $type_status=0)
    {
        $orderId = $data['out_trade_no'];
        $order = Baseorders::findOne(['OrderId' => $orderId]);
        if ($order->PayStatus > 0){
            return empty($type_status) ? false : 'fail';
        }
        $userId = $order->UserId;
        $product = Baseproducts::findOne(['ProductId' => $order->ProductId]);
        $playTbl = PlayerTbl::findOne(['PlayerID' => $userId]);
        $coin_dia_num = $product->NumCount;
        $classId = $product->ClassId;
        $transaction = Yii::$app->db->beginTransaction();
        if ($product->ClassId < 2){
            try {
                if ($product->ProductId == 2119){//一元限购大礼包
                    $diaNum = 2;//钻石2个
                    $role_time = 3;//角色小沫3天时长
                    $video_time = 3600;//视频1小时
                    $goldNum = 10000;//金币10000
                    $thing = [$diaNum,$goldNum];
                    foreach ($thing as $key=>$value){
                        self::writeXgRecord($orderId, $key);
                    }
                    $player = PlayerTbl::findOne(['PlayerID'=>$userId]);
                    $diamond = $player->Diamond + $diaNum;
                    $goldCoin = $player->GoldCoin + $goldNum;
                    PlayerTbl::updateAll(['Diamond'=>$diamond, 'GoldCoin'=>$goldCoin], 'PlayerID = :PlayerID', [':PlayerID' => $userId]);
                    $pre = DurationPermission::findOne(['user_id'=>$userId]);
                    if ($pre){
                        if (empty($pre->video_start_time)){
                            $pre->video_start_time = time();
                            $pre->video_end_time = time() + $video_time;
                        }else{
                            if ($pre->video_end_time <= time()){
                                $pre->video_end_time = time() + $video_time;
                            }else{
                                $pre->video_end_time = $pre->video_end_time + $video_time;
                            }
                        }
                    }else{
                        $pre = new DurationPermission();
                        $pre->user_id = $userId;
                        $pre->video_start_time = time();
                        $pre->video_end_time = time() + $video_time;
                    }
                    $pre->save();
                    $role = RolePlayerInfo::findOne(['playerid'=>$userId, 'role_id'=>20001]);
                    if ($role){
                        if ($role->effective_time > -1){
                            $role->effective_time = $role->effective_time + $role_time;
                            $role->save();
                        }
                    }else{
                        $role = new RolePlayerInfo();
                        $role->playerid = $userId;
                        $role->role_id = 20001;
                        $role->effective_time = $role_time;
                        $role->active_time = time();
                        $role->role_status = 1;
                        $role->save();
                    }
                    $buy = new RoleBuyRecord();
                    $buy->playerid = $userId;
                    $buy->role_id = 20001;
                    $buy->product_id = 10;
                    $buy->effective_time = 3;
                    $buy->product_status = 1;
                    $buy->buy_time = date('Y-m-d H:i:s', time());
                    $buy->save();
                    Baseorders::updateAll(['PayStatus'=>1, 'PayDate'=>date('Y-m-d H:i:s',time())], 'OrderId = :OrderId', [':OrderId' => $orderId]);
                }else{
                    if ($classId === 0){//钻石充值
                        $typestate = 'Diamond';
                        $p_coin = $playTbl->Diamond;
                    }elseif ($classId === 1){//金币充值
                        $typestate = 'GoldCoin';
                        $p_coin = $playTbl->GoldCoin;
                    }else{
                        $typestate = 'GoldCoin';
                        $p_coin = $playTbl->GoldCoin;
                    }
                    $nowNum = $p_coin + $coin_dia_num;
                    $rechargeTime = $playTbl->RechargeTimes;
//          首次充值金币或者钻石时，赠送10个钻石,[特价商品除外]
                    $productId = $order->ProductId;
                    if (empty($rechargeTime) && ($productId < 2000)){
                        if ($classId === 0){//钻石充值
                            $nowNum = $nowNum + 10;
                        }elseif($classId === 1){//金币充值
                            $p_coin = $playTbl->Diamond;
                            $goldNum = $p_coin + 10;
                            PlayerTbl::updateAll(['Diamond' => $goldNum],'PlayerID = :PlayerID',[':PlayerID'=>$userId]);
                        }
                        $stat = self::writeRecord($orderId);
                        if ($stat == false){
                            return empty($type_status) ? false : 'fail';
                        }
                    }
//          首次充值金币或者钻石时，赠送20000金币
//            if (empty($rechargeTime)){
//                if ($classId === 0){
//                    $p_coin = $playTbl->GoldCoin;
//                    $goldNum = $p_coin + 20000;
//                    PlayerTbl::updateAll(['GoldCoin' => $goldNum],'PlayerID = :PlayerID',[':PlayerID'=>$userId]);
//                }elseif($classId === 1){
//                    $nowNum = $nowNum + 20000;
//                }
//                $stat = self::writeRecord($orderId);
//                if ($stat == false){
//                    return empty($type_status) ? false : 'fail';
//                }
//            }
                    //首次充值任意金币时，赠送20000金币
//            $isgive = $playTbl->isGive;
//            if (empty($isgive) && $classId == 1){
//                $nowNum = $nowNum + 20000;
//                $stat = self::writeRecord($orderId);
//                PlayerTbl::updateAll(['isGive' => 1],'PlayerID = :PlayerID',[':PlayerID'=>$userId]);
//                if ($stat == false){
//                    return empty($type_status) ? false : 'fail';
//                }
//            }
                    //代理提点分成---【只对购买钻石类型进行分成】
                    if (empty($classId)){
                        $proservice = new ProcedureService();
                        $result = $proservice->buildProcedure($orderId);
                        if ($result['status'] <> 1){
                            return empty($type_status) ? false : 'fail';
                        }
                    }
                    //开启额外赠送
                    $extracount = 0;
                    $extrascale = 0;
                    if ($product->ExtraScale > 0){//额外比例
                        $pecal = $product->ExtraScale;
                        $ncont = $product->NumCount;
                        $extrascale = $ncont * $pecal;
                        $status = self::writeExtraRecord($orderId, $extrascale, 1);
                        if ($status == false){
                            return empty($type_status) ? false : 'fail';
                        }
                    }
                    if ($product->ExtraCount > 0){//额外个数
                        $extracount = $product->ExtraCount;
                        $status = self::writeExtraRecord($orderId, $extracount, 2);
                        if ($status == false){
                            return empty($type_status) ? false : 'fail';
                        }
                    }
                    $nowNum = $nowNum + $extrascale + $extracount;
                    PlayerTbl::updateAll([$typestate => $nowNum, 'RechargeTimes' => $rechargeTime + 1],'PlayerID = :PlayerID',[':PlayerID'=>$userId]);
                    Baseorders::updateAll(['PayStatus'=>1, 'PayDate'=>date('Y-m-d H:i:s',time())], 'OrderId = :OrderId', [':OrderId' => $orderId]);
                    self::writeRecord($orderId);
                }
                $transaction->commit();
                return empty($type_status) ? true : 'success';
            } catch (Exception $e) {
                $message  = empty($type_status) ? 'wxpay支付失败：' : 'alipay支付失败：';
                yii::getLogger()->log($message . print_r($data, true), yii\log\Logger::LEVEL_ERROR);
                $transaction->rollBack();
                return empty($type_status) ? false : 'fail';
            }
        }elseif ($product->ClassId == 2){
            try {
                if ($order->PayStatus > 0){
                    return empty($type_status) ? false : 'fail';
                }
                $userId = $order->UserId;
                $product = Baseproducts::findOne(['ProductId'=>$order->ProductId]);
                $packitemid = $product->PackId;
                $amount = $order->NumCount;
                $packitem = PackItem::findOne(['id'=>$packitemid]);
                if ($packitem->classify_id == 2){//id=2 为纪念币类型
                    //写入玩家道具记录表pack_player [同类别的累加]
                    $packplayer = PackPlayer::findOne(['item_id'=>$packitemid ,'user_id' => $userId]);
                    $pamount = 0;
                    if ($packplayer){
                        $pamount = $packplayer->amount;
                        $packplayer->amount = $amount + $pamount;
                    }else{
                        $packplayer = new PackPlayer();
                        $packplayer->user_id = $userId;
                        $packplayer->item_id = $packitemid;
                        $packplayer->amount = $amount;
                    }
                    $packplayer->save();
                }elseif (($packitem->classify_id == 6) || ($packitem->classify_id == 7)){//id=6/7 为普通月卡/至尊月卡类型
                    $permission = DurationPermission::findOne(['user_id'=>$order->UserId]);
                    if ($permission){
                        if ($packitem->classify_id == 6){//id=6 为普通月卡(30天共计720小时)
                            $end_time = $permission->ordinary_end_time;
                            if ($end_time < time()){
                                $permission->ordinary_start_time = time();
                                $permission->ordinary_end_time = time() + 3600*720;
                            }else{
                                $permission->ordinary_end_time = $end_time + 3600*720;
                            }
                        }
                        if ($packitem->classify_id == 7){//id=7 为至尊月卡
                            $end_time = $permission->super_end_time;
                            if ($end_time < time()){
                                $permission->super_start_time = time();
                                $permission->super_end_time = time() + 3600*720;
                            }else{
                                $permission->super_end_time = $end_time + 3600*720;
                            }
                        }
                    }else{
                        $permission = new DurationPermission();
                        $permission->user_id = $order->UserId;
                        if ($packitem->classify_id == 6){//id=6 为普通月卡
                            $permission->ordinary_start_time = time();
                            $permission->ordinary_end_time = time() + 3600*720;
                        }
                        if ($packitem->classify_id == 7){//id=7 为至尊月卡
                            $permission->super_start_time = time();
                            $permission->super_end_time = time() + 3600*720;
                        }
                    }
                    $permission->save();
                    //至尊月卡赠送雅静角色(角色id=20002)
                    if ($packitem->classify_id == 7){//至尊月卡
                        $roleplayer = RolePlayerInfo::findOne(['role_id'=>20002,'playerid'=>$userId]);
                        if (!$roleplayer){
                            $roleplayer = new RolePlayerInfo();
                            $roleplayer->playerid = $userId;
                            $roleplayer->role_id = 20002;
                            $roleplayer->effective_time = 30;
                            $roleplayer->active_time = time();
                            $roleplayer->role_status = 1;
                        }else{
                            $Id = $roleplayer->ID;
                            $effective_time = $roleplayer->effective_time;
                            $active_time = $roleplayer->active_time;
                            if ($effective_time < 0){//存在永久时间
                                $roleplayer->active_time = time();
                            }else{
                                $newTime = $active_time + $effective_time * 24 * 3600;
                                if ($newTime <= time()){//过期
                                    RolePlayerInfo::deleteAll(['ID'=>$Id]);
                                    $roleplayer = new RolePlayerInfo();
                                    $roleplayer->playerid = $userId;
                                    $roleplayer->role_id = 20002;
                                    $roleplayer->effective_time = 30;
                                    $roleplayer->active_time = time();
                                    $roleplayer->role_status = 1;
                                }else{
                                    $roleplayer->effective_time = $effective_time + 30;
                                }
                            }
                        }
                        $roleplayer->save();
                        //购买成功后首次发送10个钻石和10万金币
                        $sysemail = new SystemMail();
                        $sysemail->PlayerID = $userId;
                        $sysemail->MailTab = '月卡奖励';
                        $sysemail->MailTabType = 1;
                        $sysemail->MailTitle = '尊享月卡奖励发放';
                        $sysemail->Sender = '百游卡五星系统';
                        $sysemail->MailInfo = '尊贵的尊享月卡用户，今日为您奉上10钻石、10万金币，望您笑纳。尊享月卡附送的角色（雅婧）30天已激活，您可以随时到外观界面使用。';
                        $sysemail->AttachmentGoldcoin = 100000;
                        $sysemail->AttachmentDiamond = 10;
                        $sysemail->MailTime = time();
                        $sysemail->save();
                    }
                    if ($packitem->classify_id == 6){//理财月卡
                        //购买成功后首次发送2个钻石和2万金币
                        $sysemail = new SystemMail();
                        $sysemail->PlayerID = $userId;
                        $sysemail->MailTab = '月卡奖励';
                        $sysemail->MailTabType = 1;
                        $sysemail->MailTitle = '理财月卡奖励发放';
                        $sysemail->Sender = '百游卡五星系统';
                        $sysemail->MailInfo = '尊贵的理财月卡用户，今日为您奉上2钻石、2万金币，望您笑纳。';
                        $sysemail->AttachmentGoldcoin = 20000;
                        $sysemail->AttachmentDiamond = 2;
                        $sysemail->MailTime = time();
                        $sysemail->save();
                    }
                }
                //首次充值金币或者钻石时，赠送10个钻石,[特价商品除外]
                $productId = $order->ProductId;
                $rechargeTime = $playTbl->RechargeTimes;
                if (empty($rechargeTime) && ($productId < 2000)){
                    $p_coin = $playTbl->Diamond;
                    $goldNum = $p_coin + 10;
                    PlayerTbl::updateAll(['Diamond' => $goldNum],'PlayerID = :PlayerID',[':PlayerID'=>$userId]);
                    $stat = self::writeRecord($orderId);
                    if ($stat == false){
                        return empty($type_status) ? false : 'fail';
                    }
                }
                PlayerTbl::updateAll(['RechargeTimes' => $rechargeTime + 1],'PlayerID = :PlayerID',[':PlayerID'=>$userId]);
                //支付成功 修改订单状态
                Baseorders::updateAll(['PayStatus'=>1, 'PayDate'=>date('Y-m-d H:i:s',time())], 'OrderId = :OrderId', [':OrderId' => $order->OrderId]);
                //写入购买记录
                $playcurrency = new PlayerCurrencyRecordTbl();
                $playcurrency->playerId = $userId;
                $playcurrency->typeId = 3;//道具类型为3
                $playcurrency->Currency = $amount;
                $playcurrency->beforeCurrency = empty($pamount) ? 0 : $pamount;
                $playcurrency->afterCurrency = empty($pamount) ? $amount : ($amount + $pamount);
                $playcurrency->Comments = '购买背包道具：'.$packitem['name'].',数量：'.$amount;
                $playcurrency->recordDate = date('Y-m-d H:i:s', time());
                $playcurrency->AddrIp = PubService::real_ip();
                $playcurrency->adminId = 1;
                $playcurrency->save();
                $transaction->commit();
                return empty($type_status) ? true : 'success';
            } catch (Exception $e) {
                $message  = empty($type_status) ? 'wxpay道具支付失败：' : 'alipay道具支付失败：';
                yii::getLogger()->log($message . print_r($data, true), yii\log\Logger::LEVEL_ERROR);
                $transaction->rollBack();
                return empty($type_status) ? false : 'fail';
            }
        }
    }


    /**
     * @param $orderId
     * @return bool
     * 首充和购买记录写入[首充金币和钻石均赠送10个钻石]
     */
    public function writeRecord($orderId)
    {
        $transaction = yii::$app->db->beginTransaction();
        try{
            //写入充值赠送钻石记录
            $order = Baseorders::findOne(['OrderId' => $orderId]);
            $product = Baseproducts::findOne(['ProductId' => $order->ProductId]);
            $playTbl = PlayerTbl::findOne(['PlayerID' => $order->UserId]);
            $rechargeTime = $playTbl->RechargeTimes;
            $coin = $playTbl->Diamond;
            $numCount = $product->NumCount;
            if (empty($product->ClassId)){//钻石
                $beforeCurrency = $coin;
            }else{//金币
                $beforeCurrency = empty($rechargeTime) ? $coin - 10 : $playTbl->GoldCoin;
            }
            $playcurrency = new PlayerCurrencyRecordTbl();
            $playcurrency->playerId = $order->UserId;
            $playcurrency->typeId = empty($rechargeTime) ? 0 : $product->ClassId;//钻石类型为0
            $playcurrency->Currency = empty($rechargeTime) ? 10 : $numCount;
            $playcurrency->beforeCurrency = empty($rechargeTime) ? $beforeCurrency : $beforeCurrency - $numCount;
            $playcurrency->afterCurrency = empty($rechargeTime) ? $beforeCurrency + 10 : $playcurrency->beforeCurrency + $numCount;
            $playcurrency->Comments = empty($rechargeTime) ? '首充赠送钻石' : '购买商城礼包';
            $playcurrency->recordDate = date('Y-m-d H:i:s', time());
            $playcurrency->AddrIp = PubService::real_ip();
            $playcurrency->adminId = 1;

            //首充和普通充值购买写入modify数据表
            $modify = new PlayerMoneyModify();
            $modify->player_id = $order->UserId;
            if (empty($rechargeTime)){
                $modify->amount = 10;
                $modify->after = $beforeCurrency + 10;
                $modify->money_type = 1;
                $modify->info = '首充赠送钻石';
            }else{
                $modify->amount = $numCount;
                $modify->after = $playcurrency->beforeCurrency + $numCount;
                $modify->money_type = empty($product->ClassId) ? 1 : 0;
                $modify->info = '购买商城礼包';
            }
            $modify->insert_date = date('Y-m-d H:i:s', time());
            $modify->save();
            $playcurrency->save();
            $transaction->commit();
            return true;
        }catch (\Exception $e){
            $transaction->rollBack();
            yii::getLogger()->log('充值失败' . print_r($e->getMessage(), true), yii\log\Logger::LEVEL_ERROR);
            return false;
        }
    }


    public function writeXgRecord($orderId, $classId)
    {
        $transaction = yii::$app->db->beginTransaction();
        try{
            //写入一元限购大礼包记录
            $order = Baseorders::findOne(['OrderId' => $orderId]);
            $product = Baseproducts::findOne(['ProductId' => $order->ProductId]);
            $playTbl = PlayerTbl::findOne(['PlayerID' => $order->UserId]);
            if (empty($classId)){//钻石
                $numCount = 2;
                $beforeCurrency = $playTbl->Diamond;
            }else{//金币
                $numCount = 10000;
                $beforeCurrency = $playTbl->GoldCoin;
            }
            $playcurrency = new PlayerCurrencyRecordTbl();
            $playcurrency->playerId = $order->UserId;
            $playcurrency->typeId = $classId;//钻石类型为0
            $playcurrency->Currency = $numCount;
            $playcurrency->beforeCurrency = $beforeCurrency;
            $playcurrency->afterCurrency = $playcurrency->beforeCurrency + $numCount;
            $playcurrency->Comments = '购买一元限购大礼包';
            $playcurrency->recordDate = date('Y-m-d H:i:s', time());
            $playcurrency->AddrIp = PubService::real_ip();
            $playcurrency->adminId = 1;

            //首充和普通充值购买写入modify数据表
            $modify = new PlayerMoneyModify();
            $modify->player_id = $order->UserId;
            $modify->amount = $numCount;
            $modify->after = $playcurrency->beforeCurrency + $numCount;
            $modify->money_type = empty($classId) ? 1 : 0;
            $modify->info = '购买一元限购大礼包';
            $modify->insert_date = date('Y-m-d H:i:s', time());
            $modify->save();
            $playcurrency->save();
            $transaction->commit();
            return true;
        }catch (\Exception $e){
            $transaction->rollBack();
            yii::getLogger()->log('充值失败' . print_r($e->getMessage(), true), yii\log\Logger::LEVEL_ERROR);
            return false;
        }
    }

    /**
     * @param $orderId
     * @return bool
     * 首充和购买记录写入[首充金币和钻石均赠送20000金币]
     */
//    public function writeRecord($orderId)
//    {
//        //写入充值赠送金币记录
//        $order = Baseorders::findOne(['OrderId' => $orderId]);
//        $product = Baseproducts::findOne(['ProductId' => $order->ProductId]);
//        $playTbl = PlayerTbl::findOne(['PlayerID' => $order->UserId]);
//        $rechargeTime = $playTbl->RechargeTimes;
//        $coin = $playTbl->GoldCoin;
//        $numCount = $product->NumCount;
//        if (empty($product->ClassId)){
//            $beforeCurrency = empty($rechargeTime) ? $coin - 20000 : $playTbl->Diamond;
//        }else{
//            $beforeCurrency = $coin;
//        }
//        $playcurrency = new PlayerCurrencyRecordTbl();
//        $playcurrency->playerId = $order->UserId;
//        $playcurrency->typeId = empty($rechargeTime) ? 1 : $product->ClassId;
//        $playcurrency->Currency = empty($rechargeTime) ? 20000 : $numCount;
//        $playcurrency->beforeCurrency = empty($rechargeTime) ? $beforeCurrency : $beforeCurrency - $numCount;
//        $playcurrency->afterCurrency = empty($rechargeTime) ? $beforeCurrency + 20000 : $playcurrency->beforeCurrency + $numCount;
//        $playcurrency->Comments = empty($rechargeTime) ? '首充赠送金币' : '购买商城礼包';
//        $playcurrency->recordDate = date('Y-m-d H:i:s', time());
//        $playcurrency->AddrIp = PubService::real_ip();
//        $playcurrency->adminId = 1;
//        if ($playcurrency->save()){
//            return true;
//        }
//        return false;
//    }

    /**
     * @param $orderId
     * @return bool
     * 首充和购买记录写入[只是首充金币时，赠送20000金币]
     */
//    public function writeRecord($orderId)
//    {
//        //写入充值赠送金币记录
//        $order = Baseorders::findOne(['OrderId' => $orderId]);
//        $product = Baseproducts::findOne(['ProductId' => $order->ProductId]);
//        $playTbl = PlayerTbl::findOne(['PlayerID' => $order->UserId]);
//        $isgive = $playTbl->isGive;
//        $numCount = $product->NumCount;
//        if (empty($product->ClassId)){//1是金币
//            $beforeCurrency = $playTbl->Diamond;
//        }else{
//            $beforeCurrency = $playTbl->GoldCoin;
//        }
//        $playcurrency = new PlayerCurrencyRecordTbl();
//        $playcurrency->playerId = $order->UserId;
//        $playcurrency->typeId = $product->ClassId;
//        $playcurrency->Currency = (empty($isgive) && $product->ClassId == 1) ? 20000 : $numCount;
//        $playcurrency->beforeCurrency = (empty($isgive) && $product->ClassId == 1) ? $beforeCurrency : $beforeCurrency - $numCount;
//        $playcurrency->afterCurrency = (empty($isgive) && $product->ClassId == 1) ? $beforeCurrency + 20000 : $playcurrency->beforeCurrency + $numCount;
//        $playcurrency->Comments = (empty($isgive) && $product->ClassId == 1) ? '首充赠送金币' : '购买商城礼包';
//        $playcurrency->recordDate = date('Y-m-d H:i:s', time());
//        $playcurrency->AddrIp = PubService::real_ip();
//        $playcurrency->adminId = 1;
//        if ($playcurrency->save()){
//            return true;
//        }
//        return false;
//    }


    /**
     * @param $orderId
     * @return bool
     * 开启额外比例和个数写入记录
     */
    public function writeExtraRecord($orderId, $count, $type)
    {
        //写入额外比例和个数赠送记录
        $order = Baseorders::findOne(['OrderId' => $orderId]);
        $product = Baseproducts::findOne(['ProductId' => $order->ProductId]);
        $playTbl = PlayerTbl::findOne(['PlayerID' => $order->UserId]);

        if (empty($product->ClassId)){
            $beforeCurrency = $playTbl->Diamond;
        }else{
            $beforeCurrency = $playTbl->GoldCoin;
        }
        $playcurrency = new PlayerCurrencyRecordTbl();
        $playcurrency->playerId = $order->UserId;
        $playcurrency->typeId = $product->ClassId;
        $playcurrency->Currency = $count;
        $playcurrency->beforeCurrency = $beforeCurrency;
        $playcurrency->afterCurrency = $playcurrency->beforeCurrency + $count;
        $playcurrency->Comments = ($type == 1) ? '购买商城礼包额外比例赠送:'.$count : '购买商城礼包额外个数赠送:'.$count;
        $playcurrency->recordDate = date('Y-m-d H:i:s', time());
        $playcurrency->AddrIp = PubService::real_ip();
        $playcurrency->adminId = 1;
        if ($playcurrency->save()){
            return true;
        }
        return false;
    }



}